home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
SCIENTIF
/
H381.ZIP
/
GSRC208A.ZIP
/
EDRATEQ.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-13
|
20KB
|
738 lines
#include "copyleft.h"
/*
GEPASI - a simulator of metabolic pathways and other dynamical systems
Copyright (C) 1989, 1992 Pedro Mendes
*/
/*************************************/
/* */
/* GWTOP - Topology */
/* MS-WINDOWS front end */
/* */
/* User-defined kinetics */
/* */
/* QuickC/WIN 1.0 */
/* */
/* (include here compilers that */
/* compiled GWSIM successfully) */
/* */
/*************************************/
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "defines.h" /* symbols also used in .DLG files */
#include "globals.h" /* gepasi's own symbols */
#include "gwtop.h" /* macros, function prototypes, etc. */
#include "gep1.h" /* gepasi's variables */
#include "topgvar.h" /* global variables */
#include "strtbl.h" /* symbols for the string table */
#define YY_NULL 0
int rightprec( unsigned char nu );
int leftprec( unsigned char nu );
unsigned char parse_prim( void );
unsigned char parse_expr( int priority );
int lexic( char *line );
int point_error( char *b );
int yylex( void );
void yyreset( void );
void AddKLst( HWND hControl, int idx );
#pragma alloc_text( CODE1, rightprec, leftprec, parse_expr, parse_prim, lexic, point_error, EdRateq, EdRDet, EdNSub, AddKLst, EdUdkt)
int errfl, errnode;
extern char *yyin;
int rightprec( unsigned char nu )
{
int n;
n = (int) nu;
switch( tr.node[n].item )
{
case 'N':
case 'I': return 6;
case 'F': return 4;
}
switch( tr.node[n].val )
{
case '+':
case '-': return 2;
case '*':
case '/': return 4;
case ')': return 6;
case '^': return 4;
case '(':
case '%': return 0;
}
}
int leftprec( unsigned char nu )
{
int n;
n = (int) nu;
switch( tr.node[n].item )
{
case 'N':
case 'I':
case 'F': return 5;
}
switch( tr.node[n].val )
{
case '+':
case '-': return 1;
case '*':
case '/': return 3;
case '(': return 6;
case '^': return 5;
case ')':
case '%': return 0;
}
}
unsigned char parse_expr( int priority )
{
unsigned char lhs, rhs, op;
lhs = parse_prim();
if( lhs == (unsigned char) 255 ) return (unsigned char) 255;
for( ; tr.node[(int)lex].item=='O' && priority < leftprec( lex ); )
{
op = lex;
rhs = (unsigned char) 255;
++lex;
rhs = parse_expr( rightprec( op ) );
if( rhs == (unsigned char) 255 )
{
if( !errfl )
{
sprintf( errstr, "ERROR - unexpected operator" );
errnode = (int) op;
}
errfl++;
}
else
{
tr.node[(int)op].left = lhs;
tr.node[(int)op].right = rhs;
lhs = op ;
}
}
return lhs;
}
unsigned char parse_prim( void )
{
unsigned char nodep, op, primary;
char t;
nodep = (unsigned char) 255;
if( (tr.node[(int)lex].item=='N') || (tr.node[(int)lex].item=='I') ) t='K';
else t = tr.node[(int)lex].val;
switch( t )
{
case 'K': tr.node[(int)lex].left = tr.node[(int)lex].right = (unsigned char) 255;
nodep = lex;
++lex;
return nodep;
case '(': ++lex;
nodep = parse_expr( 0 );
if( (tr.node[(int)lex].item=='O') && (tr.node[(int)lex].val==')') )
{
++lex;
return nodep;
}
else
{
if( !errfl )
{
sprintf( errstr, "ERROR - right bracket missing" );
errnode = (int) lex;
}
errfl++;
}
case '+':
case '-':
case 'L':
case 'l':
case 'e':
case 'S':
case 'C': op = lex; primary = (unsigned char) 255;
++lex;
primary = parse_prim();
if( primary==(unsigned char)255 )
{
if( !errfl )
{
sprintf( errstr, "ERROR - missing operator" );
errnode = (int) op;
}
errfl++;
}
else
{
nodep = op;
tr.node[(int)op].item = 'F';
tr.node[(int)op].left = primary;
tr.node[(int)op].right = (unsigned char) 255;
return nodep;
}
default: return (unsigned char) 255;
}
if( (tr.node[(int)lex].item=='O') &&
(tr.node[(int)lex].val=='(')
)
{
++lex;
if( (tr.node[(int)lex].item=='O') &&
(tr.node[(int)lex].val==')')
)
{
tr.node[(int)lex].left = nodep;
tr.node[(int)lex].right = (unsigned char) 255;
return lex;
}
else parse_expr( 0 );
}
}
int lexic( char *line )
{
int i;
for( i=1; i<255; i++ )
tr.node[i].left = tr.node[i].right = 0;
tr.node[0].item='%';
tr.node[0].val='%';
tr.node[0].right=(unsigned char) 255;
yyreset();
tr.nnode = 1;
tr.nid = 0;
tr.nnum = 0;
yyin = line;
lex = 1;
for( errfl=0; ; )
{
if( tr.nnode==254 )
{
if( !errfl )
sprintf( errstr, "ERROR - expression too long" );
errfl++;
break;
}
if( yylex() == YY_NULL ) break;
}
if( !errfl ) tr.node[0].left = parse_expr( 0 );
if( (tr.node[tr.node[0].left].item == 'O') &&
(tr.node[tr.node[0].left].val == '(' )
)
{
sprintf( errstr, "ERROR - missing operand" );
errnode = tr.node[0].left - 1;
errfl++;
}
for( i=1; (i<tr.nnode)&&(!errfl); i++ )
{
switch( tr.node[i].item )
{
case 'O': if( ( tr.node[i].left == (unsigned char) 255 ) ||
( tr.node[i].right == (unsigned char) 255 ) ||
( tr.node[i].left == (unsigned char) 0 ) ||
( tr.node[i].right == (unsigned char) 0 )
)
if( (tr.node[i].val!='(') && (tr.node[i].val!=')') )
{
if( !errfl )
{
sprintf( errstr, "ERROR - incorrect number of operands" );
errnode = i;
}
errfl++;
}
if( !errfl )
{
if( (tr.node[tr.node[i].left].item == 'O') &&
(tr.node[tr.node[i].left].val == '(')
)
{
sprintf( errstr, "ERROR - missing operand" );
errnode = tr.node[i].left - 1;
errfl++;
}
if( (tr.node[tr.node[i].right].item == 'O') &&
(tr.node[tr.node[i].right].val == ')')
)
{
sprintf( errstr, "ERROR - missing operand" );
errnode = tr.node[i].right - 1;
errfl++;
}
}
break;
case 'I': if( ( tr.node[i].left == (unsigned char) 0 ) ||
( tr.node[i].right == (unsigned char) 0 )
)
{
if( !errfl )
{
sprintf( errstr, "ERROR - unexpected identifier" );
errnode = i-1;
}
errfl++;
}
break;
case 'N': if( ( tr.node[i].left == (unsigned char) 0 ) ||
( tr.node[i].right == (unsigned char) 0 ) )
{
if( !errfl )
{
sprintf( errstr, "ERROR - unexpected constant" );
errnode = i-1;
}
errfl++;
}
break;
}
}
return errfl;
}
int point_error( char *b )
{
int pt, i;
char astr[64];
pt = 0;
strcpy( b, "" );
for( i=1; i<tr.nnode; i++ )
{
switch( tr.node[i].item )
{
case 'N': sprintf( astr, "%g", tr.constant[(int)tr.node[i].val] ); break;
case 'I': sprintf( astr, "%s", tr.id[(int)tr.node[i].val] ); break;
case 'O': sprintf( astr, "%c", tr.node[i].val ); break;
case 'F': switch( tr.node[i].val )
{
case '+': sprintf( astr, "+" ); break;
case '-': sprintf( astr, "-" ); break;
case 'L': sprintf( astr, "log" ); break;
case 'l': sprintf( astr, "ln" ); break;
case 'e': sprintf( astr, "exp" ); break;
case 'S': sprintf( astr, "sin" ); break;
case 'C': sprintf( astr, "cos" ); break;
}
}
strcat( b, astr );
if( errfl && (errnode==i) ) pt = strlen( b );
}
if( pt==0 ) pt = strlen( b );
return pt;
}
BOOL FAR PASCAL EdRateq( HWND hDlg, WORD message, WORD wParam, LONG lParam )
{
static HWND hEdit;
char buff[2048];
int p;
switch( message )
{
case WM_INITDIALOG:
/* get the handle to the edit control */
hEdit = GetDlgItem( hDlg, IDE_M0 );
/* Limit the length of the equation to 2047 characters */
SendMessage( hEdit, EM_LIMITTEXT, (WORD) 2047, 0 );
/* if eqefl is set this is an edit of an existing kinetic type */
if( eqefl )
{
errfl = 0; /* no errors yet */
p = point_error( buff );
SendMessage( hEdit, WM_SETTEXT, 0, (DWORD) (LPSTR) buff );
SendMessage( hEdit, EM_SETSEL, 0, MAKELONG( p, p ) );
yyreset();
}
/* set the focus on the edit control */
SetFocus( hEdit );
return TRUE;
case WM_COMMAND:
switch( wParam )
{
case IDC_HELP: /* Help for this Dialog Box */
WinHelp( hDlg, (LPSTR) szHelpFile, HELP_KEY, (DWORD) (LPSTR) "Rate equation editor" );
SetFocus( hEdit );
return TRUE;
case IDOK:
SendMessage( hEdit, WM_GETTEXT, (WORD) sizeof( buff ), (DWORD) (LPSTR) buff );
if( lexic( buff ) )
{
MessageBeep( MB_OK );
MessageBox( hDlg, errstr, (LPSTR) "Rate Equation Editor", MB_ICONINFORMATION );
p = point_error( buff );
SendMessage( hEdit, WM_SETTEXT, 0, (DWORD) (LPSTR) buff );
SendMessage( hEdit, EM_SETSEL, 0, MAKELONG( p, p ) );
yyreset();
}
else
EndDialog( hDlg, IDOK );
return TRUE;
case IDCANCEL:
/* close the dialog box and return */
EndDialog( hDlg, IDCANCEL );
return TRUE;
}
default: return FALSE;
}
}
BOOL FAR PASCAL EdRDet( HWND hDlg, WORD message, WORD wParam, LONG lParam )
{
static HWND hIdLst, hEdit;
static int id_sel;
int i;
switch( message )
{
case WM_INITDIALOG:
/* get the handles to the controls */
hIdLst = GetDlgItem( hDlg, IDC_PARAMLST );
hEdit = GetDlgItem( hDlg, IDE_M0 );
SendMessage( hEdit, WM_SETTEXT, 0, (DWORD) (LPSTR) tr.descr );
if( tr.nid>0 )
{
/* insert the identifiers in the list box */
for( i=0; i<tr.nid; i++ )
SendMessage( hIdLst, LB_INSERTSTRING, i, (DWORD) (LPSTR) &tr.id[i][0] );
/* select the first id on the list */
SendMessage( hIdLst, LB_SETCURSEL, 0, 0 );
id_sel = 0;
SendDlgItemMessage( hDlg, IDRB_0E+(int)tr.id[id_sel][9], BM_SETCHECK, (WORD) 1, 0 );
SendDlgItemMessage( hDlg, IDRB_9I, BM_SETCHECK, (WORD) tr.revers, 0 );
/* set the focus on the list box */
SetFocus( hIdLst );
}
else
{
EnableWindow( hIdLst, FALSE );
for( i=IDRB_0E; i<=IDRB_1I; i++ )
EnableWindow( GetDlgItem( hDlg, i ), FALSE );
}
/* set the reversibility status */
SendMessage( GetDlgItem( hDlg, IDRB_9I ), BM_GETCHECK, (WORD) tr.revers, 0 );
/* Limit the length of the title to 64 characters */
SendMessage( hEdit, EM_LIMITTEXT, (WORD) 64, 0 );
return TRUE;
case WM_COMMAND:
switch( wParam )
{
case IDC_PARAMLST:
if( HIWORD( lParam ) == LBN_SELCHANGE )
{
id_sel = (int) SendMessage( hIdLst, LB_GETCURSEL, 0, 0 );
for(i=IDRB_0E; i<=IDRB_1I; i++ )
SendDlgItemMessage( hDlg, i, BM_SETCHECK, 0, 0 );
SendDlgItemMessage( hDlg, IDRB_0E+(int)tr.id[id_sel][9], BM_SETCHECK, (WORD) 1, 0 );
return TRUE;
}
else return FALSE;
case IDRB_0E:
tr.id[id_sel][9] = (char) 0;
return TRUE;
case IDRB_0I:
tr.id[id_sel][9] = (char) 1;
return TRUE;
case IDRB_1E:
tr.id[id_sel][9] = (char) 2;
return TRUE;
case IDRB_1I:
tr.id[id_sel][9] = (char) 3;
return TRUE;
case IDRB_9I:
if( SendMessage( GetDlgItem( hDlg, IDRB_9I ), BM_GETCHECK, 0, 0 ) )
tr.revers = 1;
else
tr.revers = 0;
return TRUE;
case IDC_HELP: /* Help for this Dialog Box */
WinHelp( hDlg, (LPSTR) szHelpFile, HELP_KEY, (DWORD) (LPSTR) "Rate equation details" );
SetFocus( hEdit );
return TRUE;
case IDOK:
SendMessage( hEdit, WM_GETTEXT, (WORD) sizeof( tr.descr ), (DWORD) (LPSTR) &tr.descr[0] );
if( strlen( tr.descr ) == 0 )
{
LoadString( hInst, IDS_ERR_NO_NAME, szString, sizeof(szString) );
MessageBeep( MB_OK );
MessageBox(hDlg, szString, NULL, MB_ICONINFORMATION);
return TRUE;
}
EndDialog( hDlg, IDOK );
return TRUE;
case IDCANCEL:
/* close the dialog box and return */
EndDialog( hDlg, IDCANCEL );
return TRUE;
}
default: return FALSE;
}
}
BOOL FAR PASCAL EdNSub( HWND hDlg, WORD message, WORD wParam, LONG lParam )
{
static HWND hEdit, hEdit2;
char auxstr[33];
static int s, p;
switch( message )
{
case WM_INITDIALOG:
/* get the handles to the edit controls */
hEdit = GetDlgItem( hDlg, IDE_M0 );
hEdit2 = GetDlgItem( hDlg, IDE_M1 );
/* Limit the length of the text to 32 characters */
SendMessage( hEdit, EM_LIMITTEXT, (WORD) 32, 0 );
SendMessage( hEdit2, EM_LIMITTEXT, (WORD) 32, 0 );
wsprintf( (LPSTR) auxstr, "%d", tr.nsub );
SendMessage( hEdit, WM_SETTEXT, 0, (DWORD) (LPSTR) auxstr );
wsprintf( (LPSTR) auxstr, "%d", tr.npro );
SendMessage( hEdit2, WM_SETTEXT, 0, (DWORD) (LPSTR) auxstr );
return TRUE;
case WM_COMMAND:
switch( wParam )
{
case IDC_HELP: /* Help for this Dialog Box */
WinHelp( hDlg, (LPSTR) szHelpFile, HELP_KEY, (DWORD) (LPSTR) "Number of substrates" );
SetFocus( hEdit );
return TRUE;
case IDOK:
SendMessage( hEdit2, WM_GETTEXT, (WORD) sizeof( auxstr ), (DWORD) (LPSTR) auxstr );
tr.npro = atoi( auxstr );
SendMessage( hEdit, WM_GETTEXT, (WORD) sizeof( auxstr ), (DWORD) (LPSTR) auxstr );
tr.nsub = atoi( auxstr );
if( tr.nsub<0 )
{
LoadString( hInst, IDS_ERR_NEG, szString, sizeof(szString) );
MessageBeep( MB_OK );
MessageBox(hDlg, szString, NULL, MB_ICONINFORMATION);
SetFocus( hEdit );
return TRUE;
}
if( (tr.revers) && (tr.nsub==0) )
{
LoadString( hInst, IDS_ERR_NO_SUBS, szString, sizeof(szString) );
MessageBeep( MB_OK );
MessageBox(hDlg, szString, NULL, MB_ICONINFORMATION);
SetFocus( hEdit );
return TRUE;
}
if( tr.npro<0 )
{
LoadString( hInst, IDS_ERR_NEG, szString, sizeof(szString) );
MessageBeep( MB_OK );
MessageBox(hDlg, szString, NULL, MB_ICONINFORMATION);
SetFocus( hEdit2 );
return TRUE;
}
if( (tr.revers) && (tr.npro==0) )
{
LoadString( hInst, IDS_ERR_NO_PRODS, szString, sizeof(szString) );
MessageBeep( MB_OK );
MessageBox(hDlg, szString, NULL, MB_ICONINFORMATION);
SetFocus( hEdit2 );
return TRUE;
}
EndDialog( hDlg, IDOK );
return TRUE;
case IDCANCEL:
/* close the dialog box and return */
EndDialog( hDlg, IDCANCEL );
return TRUE;
}
default: return FALSE;
}
}
void AddKLst( HWND hControl, int idx )
{
int i;
WORD ElWidth;
HANDLE hDC;
hDC = GetDC( hControl );
ElWidth = 5 + LOWORD( GetTextExtent( hDC, tree[idx].descr, _fstrlen(tree[idx].descr) ) );
SetTextJustification( hDC, 0, 0 );
ReleaseDC( hControl, hDC );
if( ElWidth > (WORD) lbWidth )
{
lbWidth = ElWidth;
SendMessage( hControl, LB_SETHORIZONTALEXTENT, lbWidth, 0 );
}
if( eqefl )
{
SendMessage( hControl, LB_DELETESTRING, idx, 0 );
SendMessage( hControl, LB_INSERTSTRING, idx, (DWORD) tree[idx].descr );
}
else
{
SendMessage( hControl, LB_INSERTSTRING, -1, (DWORD) tree[idx].descr );
SendMessage( hControl, WM_VSCROLL, SB_BOTTOM, 0 );
}
}
BOOL FAR PASCAL EdUdkt(HWND hDlg, WORD Message, WORD wParam, LONG lParam)
{
static HWND hSelect, hButt, hDel;
static int eqidx;
int i,j,nRc;
FARPROC lpfnProc2;
switch( Message )
{
case WM_INITDIALOG:
/* get handles for controls */
hSelect = GetDlgItem( hDlg, IDC_KINETLST );
hButt = GetDlgItem( hDlg, IDC_CHANGE );
hDel = GetDlgItem( hDlg, IDC_DEL );
/* initialize hSelect: add all rate equations */
for( i=0, lbWidth=0; i<nudf; i++ )
AddKLst( hSelect, i );
if( nudf==0 )
{
EnableWindow( hButt, FALSE );
EnableWindow( hDel, FALSE );
}
else SendMessage( hSelect, LB_SETCURSEL, 0, 0 );
return TRUE;
case WM_USER+1:
lpfnProc2 = MakeProcInstance((FARPROC) EdRateq, hInst);
nRc = DialogBox(hInst, (LPSTR)"EDRATEQ", hDlg, lpfnProc2);
FreeProcInstance(lpfnProc2);
if( nRc == IDOK )
{
if( eqefl )
for( i=0; i<tr.nid; i++ )
for( j=0; j<tree[eqidx].nid; j++ )
if( ! lstrcmp( &tr.id[i][0], &tree[eqidx].id[j][0] ) )
tr.id[i][9] = tree[eqidx].id[j][9];
lpfnProc2 = MakeProcInstance((FARPROC) EdRDet, hInst);
nRc = DialogBox(hInst, (LPSTR)"ED_RDET", hDlg, lpfnProc2);
FreeProcInstance(lpfnProc2);
if( nRc == IDOK )
{
tidy_tree();
if( (!tr.revers) ||
( (tr.revers) && (tr.nsub==0) ) ||
( (tr.revers) && (tr.npro==0) )
)
{
lpfnProc2 = MakeProcInstance((FARPROC) EdNSub, hInst);
nRc = DialogBox(hInst, (LPSTR)"ED_NSUB", hDlg, lpfnProc2);
FreeProcInstance(lpfnProc2);
if( nRc != IDOK ) return TRUE;
}
new_tree( eqidx );
new_rateq( eqidx );
AddKLst( hSelect, eqidx );
}
}
return TRUE;
case WM_COMMAND:
switch(wParam)
{
case IDC_ADD:
eqefl = 0; eqidx = nudf;
_fmemset( (void __far*) &tr, 0, sizeof( struct treet ) );
SendMessage( hDlg, WM_USER+1, 0, 0 );
return TRUE;
case IDC_CHANGE:
/* get the index of the element selected */
eqidx = (int) SendMessage( hSelect, LB_GETCURSEL, 0, 0 );
if( eqidx != LB_ERR )
{
/* signal that it is a change, not a new one */
eqefl = 1;
/* copy it to the edit tree structure */
_fmemcpy( (void __far*) &tr, (void __far*) &(tree[eqidx]), sizeof( struct treet ) );
SendMessage( hDlg, WM_USER+1, 0, 0 );
}
return TRUE;
case IDC_KINETLST:
if( HIWORD( lParam ) == LBN_DBLCLK )
{
SendMessage( hDlg, WM_COMMAND, IDC_CHANGE, 0 );
return TRUE;
}
else return FALSE;
case IDC_HELP: /* Help on this Dialog Box */
WinHelp( hDlg, (LPSTR) szHelpFile, HELP_KEY, (DWORD) (LPSTR) "Kinetic types database" );
return TRUE;
case IDOK:
EndDialog(hDlg, IDOK);
return TRUE;
} /* End of WM_COMMAND */
return FALSE;
default:
return FALSE;
}
} /* End of METABMsgProc */